<?php
/**
 * 用户管理
 * @since   2018-02-06
 * @author  zhaoxiang <zhaoxiang051405@gmail.com>
 */

namespace app\admin\controller;


use app\constant\UserConst;
use app\helper\SmsHelper;
use app\model\AdminAuthGroup;
use app\model\AdminAuthGroupAccess;
use app\model\AdminTenant;
use app\model\AdminUser;
use app\model\AdminUserData;
use app\util\ReturnCode;
use app\util\Tools;
use think\Db;
use think\Exception;

class User extends Base
{

    /**
     * 获取用户列表
     * @return array
     * @throws \think\exception\DbException
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    public function index()
    {

        $limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
        $start = $this->request->get('page', 1);
        $type = $this->request->get('type', '', 'intval');
        $keywords = $this->request->get('keywords', '');
        $status = $this->request->get('status', '');

        $obj = new AdminUser();

        $where = [];
        if (Tools::isAdministrator($this->userInfo['id'])) {
            $where['type'] = ['<>', UserConst::ADMIN_USER];
        } else {
            //添加站点筛选
            $obj = $obj->where($this->addTid($where, true));
        }
        if (strlen($status)) {
            $where['status'] = $status;
        }

        if ($type) {
            switch ($type) {
                case 1:
                    $obj = $obj->whereLike('username', "%{$keywords}%");
                    break;
                case 2:
                    $obj = $obj->whereLike('nickname', "%{$keywords}%");
                    break;
            }
        }

        $listObj = $obj->order('create_time DESC')
            ->paginate($limit, false, ['page' => $start])->each(function ($item, $key) {
                $item->userData;
            })->toArray();
        $listInfo = $listObj['data'];
        $idArr = array_column($listInfo, 'id');

        $userGroup = AdminAuthGroupAccess::all(function ($query) use ($idArr) {
            $query->whereIn('uid', $idArr);
        });
        $userGroup = Tools::buildArrFromObj($userGroup);
        $userGroup = Tools::buildArrByNewKey($userGroup, 'uid');


        foreach ($listInfo as $key => &$value) {
            if ($value['userData']) {
                $value['userData']['last_login_ip'] = long2ip(intval($value['userData']['last_login_ip']));
                $value['userData']['last_login_time'] = date('Y-m-d H:i:s', $value['userData']['last_login_time']);
                $value['create_ip'] = long2ip(intval($value['create_ip']));
                if (isset($userGroup[$value['id']])) {
//                    $listInfo[$key]['group_id'] = explode(',', $userGroup[$value['id']]['group_id']);
                    $listInfo[$key]['group_id'] = $userGroup[$value['id']]['group_id'];
                } else {
                    $listInfo[$key]['group_id'] = '';
                }
            }
        }

        return $this->buildSuccess([
            'list' => $listInfo,
            'count' => $listObj['total']
        ]);
    }

    /**
     * 新增用户
     * @return array
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    public function add()
    {
        $groups = '';
        $postData = $this->request->post();
        $postData['create_ip'] = request()->ip(1);
        $postData['password'] = Tools::userMd5($postData['password']);
        if (isset($postData['group_id']) && $postData['group_id']) {
//            $groups = trim(implode(',', $postData['group_id']), ',');
            $groups = $postData['group_id'];
            unset($postData['group_id']);
        }
        $postData = $this->addTid($postData);
        $res = AdminUser::create($postData);
        if ($res === false) {
            return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
        } else {
            $data = ['uid' => $res->id, 'group_id' => $groups];
            AdminAuthGroupAccess::create($data);

            return $this->buildSuccess([]);
        }
    }

    /**
     * 获取当前组的全部用户
     * @return array
     * @throws \think\Exception
     * @throws \think\exception\DbException
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    public function getUsers()
    {
        $limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
        $page = $this->request->get('page', 1);
        $gid = $this->request->get('gid', 0);
        if (!$gid) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, '非法操作');
        }
        $model = AdminAuthGroup::get($this->addTid(['id' => $gid]));
        if (!$model) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, '非法操作');
        }
        $totalNum = (new AdminAuthGroupAccess())->where('find_in_set("' . $gid . '", `group_id`)')->count();
        $start = $limit * ($page - 1);
        $sql = "SELECT au.* FROM admin_user as au LEFT JOIN admin_auth_group_access as aaga " .
            " ON aaga.`uid` = au.`id` WHERE find_in_set('{$gid}', aaga.`group_id`) " .
            " ORDER BY au.create_time DESC LIMIT {$start}, {$limit}";
        $userInfo = Db::query($sql);

        $uidArr = array_column($userInfo, 'id');
        $userData = (new AdminUserData())->whereIn('uid', $uidArr)->select();
        $userData = Tools::buildArrByNewKey($userData, 'uid');

        foreach ($userInfo as $key => $value) {
            if (isset($userData[$value['id']])) {
                $userInfo[$key]['last_login_ip'] = long2ip($userData[$value['id']]['last_login_ip']);
                $userInfo[$key]['login_times'] = $userData[$value['id']]['login_times'];
                $userInfo[$key]['last_login_time'] = date('Y-m-d H:i:s', $userData[$value['id']]['last_login_time']);
            }
            $userInfo[$key]['create_ip'] = long2ip(intval($userInfo[$key]['create_ip']));
        }

        return $this->buildSuccess([
            'list' => $userInfo,
            'count' => $totalNum
        ]);
    }

    /**
     * 用户状态编辑
     * @return array
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    public function changeStatus()
    {
        $id = $this->request->get('id');
        $status = $this->request->get('status');

        $res = AdminUser::update([
            'id' => $id,
            'status' => $status
        ]);
        if ($res === false) {
            return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
        } else {
            return $this->buildSuccess([]);
        }
    }

    /**
     * 编辑用户
     * @return array
     * @throws \think\exception\DbException
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    public function edit()
    {
        $groups = '';
        $postData = $this->request->post();
        if ($postData['password'] === 'ApiAdmin') {
            unset($postData['password']);
        } else {
            $postData['password'] = Tools::userMd5($postData['password']);
        }
        if (isset($postData['group_id']) && $postData['group_id']) {
//            $groups = trim(implode(',', $postData['group_id']), ',');
            $groups = $postData['group_id'];
            unset($postData['group_id']);
        }
        $postData = $this->addTid($postData);
        $res = AdminUser::update($postData);
        if ($res === false) {
            return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
        } else {
            $has = AdminAuthGroupAccess::get(['uid' => $postData['id']]);
            if ($has) {
                AdminAuthGroupAccess::update([
                    'group_id' => $groups
                ], [
                    'uid' => $postData['id'],
                ]);
            } else {
                AdminAuthGroupAccess::create([
                    'uid' => $postData['id'],
                    'group_id' => $groups
                ]);
            }

            return $this->buildSuccess([]);
        }
    }

    /**
     * 修改自己的信息
     * @return array
     * @throws \think\exception\DbException
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    public function own()
    {
        $postData = $this->request->post();
        $headImg = $postData['head_img'];

        if ($postData['password'] && $postData['oldPassword']) {
            $oldPass = Tools::userMd5($postData['oldPassword']);
            unset($postData['oldPassword']);
            if ($oldPass === $this->userInfo['password']) {
                $postData['password'] = Tools::userMd5($postData['password']);
            } else {
                return $this->buildFailed(ReturnCode::INVALID, '原始密码不正确');
            }
        } else {
            unset($postData['password']);
            unset($postData['oldPassword']);
        }
        unset($postData['type']);
        $postData['id'] = $this->userInfo['id'];
        unset($postData['head_img']);
        $res = AdminUser::update($postData);
        if ($res === false) {
            return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
        } else {
            $userData = AdminUserData::get(['uid' => $postData['id']]);
            $userData->head_img = $headImg;
            $userData->save();

            return $this->buildSuccess([]);
        }
    }

    /**
     * 删除用户
     * @return array
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    public function del()
    {
        $id = $this->request->get('id');
        if (!$id) {
            return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
        }
        if ($id == $this->userInfo['id']) {
            return $this->buildFailed(ReturnCode::AUTH_REFUSE, '不能自己删除自己');
        }
        $model = AdminTenant::get(['uid' => $id]);
        if ($model) {
            return $this->buildFailed(ReturnCode::AUTH_REFUSE, '站长用户不可删除');
        }
        $isAdmin = Tools::isAdministrator($id);
        if ($isAdmin) {
            return $this->buildFailed(ReturnCode::AUTH_REFUSE, '超级管理员不能被删除');
        }
        $model = AdminUser::get($this->addTid(['id' => $id]));
        if ($model) {
            Db::startTrans();
            try {
                $success1 = AdminUser::destroy($id);
                $success2 = AdminAuthGroupAccess::destroy(['uid' => $id]);
                if ($success1 && $success2) {
                    Db::commit();
                    return $this->buildSuccess([]);
                }
            } catch (Exception $e) {
                Db::rollback();
            }

        }
        return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '删除失败');
    }

    /**
     * 注册
     * @return array
     * @author chniccs
     */
    public function register()
    {

        $postData = $this->request->post();
        $userName = $postData['username'];
        $has = AdminUser::get(['username' => $userName]);
        if ($has) {
            return $this->buildFailed(ReturnCode::FAILED, '帐号已经注册过了');
        }
        // 验证短信
        $type = request()->param("type");
        $code = request()->param("code");
        $result = SmsHelper::checkSms($type, $userName, $code, true);
        if (!$result) {
            return $this->buildFailed(ReturnCode::FAILED, '验证码验证失败', null);
        }
        //注册流程
        $values = [];
        $values['regIp'] = (float)(request()->ip(1));
        $values['regTime'] = time();
        $values['username'] = $userName;
        $values['nickname'] = $postData['nickname'];
        $values['password'] = Tools::userMd5($postData['password']);
        unset($postData['groupId']);
        Db::startTrans();
        try {
            $res = AdminUser::create($values);
            if ($res === false) {
                return $this->buildFailed(ReturnCode::FAILED, '操作失败');
            } else {
                $group = config('apiadmin.USER_TENANT_ADMIN_GROUP');
                $tenantRes = AdminTenant::create([
                    'uid' => $res->id,
                    'expiration_time' => date('Y-m-d H:i:s', strtotime('+15day')),//15天的试用期
                ]);
                if ($tenantRes) {
                    $res->setAttr('tid', $tenantRes->id);
                    $affected = $res->allowField(true)->save();
                    if (empty($affected)) {
                        throw new Exception();
                    }
                } else {
                    throw new Exception();
                }

                //写入权限组
                AdminAuthGroupAccess::create([
                    'uid' => $res->id,
                    'group_id' => $group
                ]);
                Db::commit();
                return $this->buildSuccess([]);
            }

        } catch (Exception $e) {
        }
        Db::rollback();
        return $this->buildFailed(ReturnCode::FAILED, '操作失败');
    }

    /**
     * 重置密码
     * @return array
     * @author chniccs
     * @throws \think\exception\DbException
     */
    public function forgot()
    {
        $postData = $this->request->post();
        $userName = $postData['username'];
        $has = AdminUser::get(['username' => $userName]);
        if (!$has) {
            return $this->buildFailed(ReturnCode::FAILED, '当前帐号未注册过');
        }
        // 验证短信
        $type = request()->param("type");
        $code = request()->param("code");
        $result = SmsHelper::checkSms($type, $userName, $code, true);
        if (!$result) {
            return $this->buildFailed(ReturnCode::FAILED, '验证码验证失败', null);
        }
        //修改密码
        $password = Tools::userMd5($postData['password']);
        $res = AdminUser::update([
            'id' => $has['id'],
            'password' => $password
        ]);
        if ($res === false) {
            return $this->buildFailed(ReturnCode::FAILED, '操作失败');
        } else {
            return $this->buildSuccess([]);
        }
    }

}
